/**
 * 给定一个经过编码的字符串，返回它解码后的字符串。

编码规则为: k[encoded_string]，表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的；输入字符串中没有额外的空格，且输入的方括号总是符合格式要求的。

此外，你可以认为原始数据不包含数字，所有的数字只表示重复的次数 k ，例如不会出现像 3a 或 2[4] 的输入。

 

示例 1：

输入：s = "3[a]2[bc]"
输出："aaabcbc"
示例 2：

输入：s = "3[a2[c]]"
输出："accaccacc"
示例 3：

输入：s = "2[abc]3[cd]ef"
输出："abcabccdcdcdef"
示例 4：

输入：s = "abc3[cd]xyz"
输出："abccdcdcdxyz"
 */

export function decodeString(s: string): string {
    const strArr = s.split('');
    let middleStr = '';
    let allStr = '';
    const stackArr: any[] = [];
    function popStackUntil(arr: any[]) {
        let temStr = '';
        for(let len = arr.length; len >= 0; len--) {
            const popItem = arr.pop();
            if ((popItem !== '[') && typeof temStr === 'string') {
                temStr = popItem + temStr;
            } else if (popItem === '[') {
                return temStr;
            }
        }
        return '';
    }
    function computeStr(str: string, time: number) {
        let tempStr = '';
        for(let i = 1; i <= time; i++) {
            tempStr += str;
        }
        return tempStr;
    }
    strArr.forEach(sItem => {
        const n = Number(sItem);
        if (!isNaN(n)) {
            const len = stackArr.length;
            if (typeof stackArr[len -1] === 'number') {
                stackArr[len - 1] = Number(stackArr[len - 1] + sItem);
            } else {
                stackArr.push(n);
            }
        } else if (sItem === '[') {
            stackArr.push(sItem);
        } else if (sItem === ']') {
            const tempStr = popStackUntil(stackArr);
            const len = stackArr.length;
            let time;
            // 边界情况，连续两个 [[abc]] 包裹
            if (stackArr[len - 1] === '[') {
                time = 1;
            } else if (typeof stackArr[len - 1] === 'number') {
                time = stackArr.pop();
            }
            middleStr = computeStr(tempStr + middleStr, time);
        } else if (isNaN(n)) {
            if (stackArr.length) {
                stackArr.push(sItem);
            } else {
                allStr += sItem;
            }
        }
        if (!stackArr.length) {
            allStr += middleStr;
            middleStr = '';
        }
    })
    return allStr;
};